﻿//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	NotificationJob.cs
//  Developer:	Solomatov Igor
//  Created:	16.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Threading;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Smart.Common.Notifications;

namespace Smart.Common.Jobs
{
	/// <summary>
	/// Notification sender job
	/// </summary>
	public class NotificationJob : SPJob
	{
		/// <summary>
		/// Notification sender job
		/// </summary>
		public NotificationJob()
		{
		}

		/// <summary>
		/// Notification sender job
		/// </summary>
		public NotificationJob(string jobName, SPSite site, SPWeb web)
			: base(jobName, jobName, site, web)
		{
		}

		public static int ExecuteInternalExecuting = 0;

		/// <summary>
		/// Sends emails
		/// </summary>
		protected override void ExecuteInternal()
		{
			var wasExecuting = Interlocked.CompareExchange(ref ExecuteInternalExecuting, 1, 0);

			if (wasExecuting != 0)
			{
				UpdateProgress(5);

				H.LT("NotificationJob.ExecuteInternal.AlreadyRunnungException: send email is already in progress!");

				UpdateProgress(100);

				return;
			}

			try
			{
				UpdateProgress(5);

				using (var notificationScope = SPServices.Notifications)
				using (new UnsafeUpdate(notificationScope.Web))
				{
					var notifications =
						notificationScope.Queue.Query.Where
							.Leq(Const.Guids.NotificationItem.SendAt.ToString(), DateTime.Now, true)
						.Executor.Execute(Const.TimerJobs.Notification.OneTimeMessagesCount);

					UpdateProgress(50);

					for (var i = 0; i < notifications.Count; i++)
					{
						// Update progress every 16 email
						if ((i & 0xF) == 0)
							UpdateProgress(50 + i * 50 / notifications.Count);

						// Send notification and remove item (if needed)
						notifications[i].Send();
					}

					UpdateProgress(100);
				}
			}
			catch (Exception ex)
			{
				H.LX("NotificationJob.ExecuteInternal", ex);
			}
			finally
			{
				Interlocked.Exchange(ref ExecuteInternalExecuting, 0);
			}
		}

		/// <summary>
		/// Every 2 minutes
		/// </summary>
		public override SPSchedule DefaultShedule
		{
			get { return new SPMinuteSchedule { BeginSecond = 0, EndSecond = 59, Interval = 2 }; }
		}
	}
}